package MyScanner;

//Token类，记录每一个Token的各项属性，并提供相应的字符串转换方式。
public class Token {

    //属性字类型
    public enum TokenTypes
    {
        IDENTIFIER,
        KEYWORD,
        INTEGER_CONSTANT,
        FLOATING_CONSTANT,
        CHARACTER_CONSTANT,
        STRING_LITERAL,
        OPERATORS,
        EOF,
        ERROR
    }

    private final String content;     //token原内容
    private TokenTypes type;    //token类型
    private final Integer id;         //token序号
    private final Integer stNum;      //token起始编号
    private final Integer edNum;      //token结束编号
    private final Integer stRow;      //token起始行。
    private final Integer stCol;      //token起始列。

    public Token(String content, TokenTypes type, Integer id, Integer stNum, Integer edNum, Integer stRow, Integer stCol)
    {
        this.content = content;
        this.type = type;
        this.id = id;
        this.stNum = stNum;
        this.edNum = edNum;
        this.stRow = stRow;
        this.stCol = stCol;

        //保留字判断
        if(this.type == TokenTypes.IDENTIFIER && StdElements.isKeyWords(this.content))
        {
            this.type = TokenTypes.KEYWORD;
        }
    }

    @Override
    public String toString() {
        String actualType;
        actualType = mappingTokenTypeToActualType(this);
        if(actualType == null) {
            System.out.println("Error: Can't find tokenType");
            return null;
        }
        return "[@" +
                id +
                "," +
                stNum +
                ":" +
                edNum +
                "=" +
                "'" +
                content +
                "'" +
                "," +
                "<" +
                actualType +
                ">" +
                "," +
                stRow +
                ":" +
                stCol +
                "]";
    }


    private static String mappingTokenTypeToActualType(Token token)
    {
        if(token == null)
            return null;
        if(token.type == TokenTypes.IDENTIFIER)
            return "Identifier";
        if(token.type == TokenTypes.KEYWORD)
            return "'" + token.content + "'";
        if(token.type == TokenTypes.INTEGER_CONSTANT)
            return "IntegerConstant";
        if(token.type == TokenTypes.FLOATING_CONSTANT)
            return "FloatingConstant";
        if(token.type == TokenTypes.CHARACTER_CONSTANT)
            return "CharacterConstant";
        if(token.type == TokenTypes.STRING_LITERAL)
            return "StringLiteral";
        if(token.type == TokenTypes.OPERATORS)
            return "'" + token.content + "'";
        if(token.type == TokenTypes.EOF)
            return "EOF";
        return null;
    }

    public static TokenTypes mappingDFAEndStateToTokenType(DFA.STATE state)
    {
        if(state == DFA.STATE.CHARACTER_CONSTANT)
            return TokenTypes.CHARACTER_CONSTANT;
        else if(state == DFA.STATE.EOF)
            return TokenTypes.EOF;
        else if(state == DFA.STATE.IDENTIFIER)
            return TokenTypes.IDENTIFIER;
        else if(state == DFA.STATE.KEYWORD)
            return TokenTypes.KEYWORD;
        else if(state == DFA.STATE.FLOATING_CONSTANT)
            return  TokenTypes.FLOATING_CONSTANT;
        else if(state == DFA.STATE.INTEGER_CONSTANT)
            return TokenTypes.INTEGER_CONSTANT;
        else if(state == DFA.STATE.OPERATORS)
            return  TokenTypes.OPERATORS;
        else if(state == DFA.STATE.STRING_LITERAL)
            return  TokenTypes.STRING_LITERAL;
        else
            return TokenTypes.ERROR;
    }

    public String getContent()
    {
        return content;
    }

}
